\chapter{Node Architecture}
\label{cha:node-architecture}


\section{Overview}

This chapter describes the architecture of INET host and router models.

Hosts and routers in the INET Framework are OMNeT++ compound modules that
are composed of the following ingredients:

\begin{itemize}

\item \tbf{Interface Table (\nedtype{InterfaceTable})}. This module
contains the table of network interfaces (eth0, wlan0, etc) in the host.
Interfaces are registered dynamically during the initialization phase by
modules that represent network interface cards (NICs). Other modules access
interface information via a C++ class interface.

\item \tbf{Routing Table (\nedtype{IPv4RoutingTable})}. This module contains
the IPv4 routing table. It is also accessed from other modules via a C++ interface.
The interface contains member functions for adding, removing, enumerating
and looking up routes, and finding the best matching route for a given
destination IPv4 address. The IPv4 module calls the latter function for
routing packets, and routing protocols such as OSPF or BGP call the route
manipulation methods to add and manage discovered routes. For IPv6
simulations, \nedtype{IPv4RoutingTable} is replaced (or co-exists) with
a \nedtype{IPv6RoutingTable} module, possibly with a \nedtype{BindingCache}
module as well.

\ifdraft TODO
; and for Mobile IPv6 simulations (xMIPv6 project [TODO])
\fi

\ifdraft TODO
\item \tbf{Notification Board (\nedtype{NotificationBoard})}. This module
makes it possible for several modules to communicate in a publish-subscribe
manner. Notifications include change notifications (``routing table
changed'') and state changes (``radio became idle'').
\fi

\item \tbf{Mobility module}. In simulations involving node mobility, this
module is responsible for moving around the node in the simulated
``playground.'' A mobility module is also needed for wireless simulations
even if the node is stationary, because the mobility module stores the
node's location, needed to compute wireless transmissions. Different
mobility models (Random Walk, etc.) are supported via different module
types, and many host models define their mobility submodules with
parametric type so that the mobility model can be changed in the
configuration (\ttt{"mobility: <mobilityType> like IMobility"}).

\item \tbf{NICs}. Network interfaces are usually compound modules
themselves, composed of a queue and a MAC module (and in the case of
wireless NICs, a radio module or modules). Examples are
\nedtype{PPPInterface}, \nedtype{EthernetInterface}, and WLAN interfaces
such as \nedtype{Ieee80211NicSTA}. The queue submodule stores packets
waiting for transmission, and it is usually defined as having parametric
type as it has multiple implementations to accommodate different needs
(\nedtype{DropTailQueue}, \nedtype{REDQueue}, \nedtype{DropTailQoSQueue},
etc.) Most MACs also have an internal queue to allow operation without an
external queue module, the advantage being smaller overhead. The NIC's
entry in the host's \nedtype{InterfaceTable} is usually registered by the
MAC module at the beginning of the simulation.

\item \tbf{Network layer}. Modules that represent protocols of the network
layer are usually grouped into a compound module: \nedtype{IPv4NetworkLayer}
for IPv4, and \nedtype{IPv6NetworkLayer} for IPv6. \nedtype{IPv4NetworkLayer}
contains the modules \nedtype{IPv4}, \nedtype{ARP}, \nedtype{ICMP} and
\nedtype{ErrorHandling}. The \nedtype{IPv4} module performs IP
encapsulation/decapsulation and routing of datagrams; for the latter it
accesses the C++ function call interface of the \nedtype{IPv4RoutingTable}.
Packet forwarding can be turned on/off via a module parameter. The
\nedtype{ARP} module is put into the path of packets leaving the network
layer towards the NICs, and performs address resolution for interfaces that
need it (e.g. Ethernet). \nedtype{ICMP} deals with sending and receiving
ICMP packets. The \nedtype{ErrorHandling} module receives and logs ICMP
error replies. The IPv6 network layer, \nedtype{IPv6NetworkLayer} contains the
modules \nedtype{IPv6}, \nedtype{ICMPv6}, \nedtype{IPv6NeighbourDiscovery}
and \nedtype{IPv6ErrorHandling}. For Mobile IPv6 simulations 

\ifdraft TODO
(xMIPv6 project [TODO]),
\fi

\nedtype{IPv6NetworkLayer} is extended with further modules.

\item \tbf{Transport layer protocols}. Transport protocols are represented
by modules connected to the network layer; currently TCP, UDP and SCTP are
supported. TCP has several implementations: \nedtype{TCP} is the OMNeT++
native implementation; the \nedtype{TCP\_lwip} module wraps the lwIP TCP
stack \ifdraft [TODO] \fi; and the \nedtype{TCP\_NSC} module wraps the Network
Simulation Cradle library \ifdraft [TODO] \fi. For this reason, the \ttt{tcp} 
submodule is usually defined with a parametric submodule type (\ttt{"tcp:
<tcpType> like ITCP"}). UDP and SCTP are implemented by the \nedtype{UDP} and
\nedtype{SCTP} modules, respectively.

\item \sloppypar \tbf{Applications}. Application modules typically connect to TCP
and/or UDP, and model the user behavior as well as the application program
(e.g. browser) and application layer protocol (e.g. HTTP). For convenience,
\nedtype{StandardHost} supports any number of UDP, TCP and SCTP
applications, their types being parametric (\ttt{"tcpApp[numTcpApps]:
<tcpAppType> like TCPApp; udpApp[numUdpApps]: <udpAppType> like
UDPApp; ..."}). This way the user can configure applications entirely from
\ttt{omnetpp.ini}, and does not need to write a new NED file every time
different applications are needed in a host model. Application modules
are typically not present in router models.

\item \tbf{Routing protocols}. Router models typically contain modules that
implement routing protocols such as OSPF or BGP. These modules are
connected to the TCP and/or the UDP module, and manipulate routes in the
\nedtype{IPv4RoutingTable} module via C++ function calls.

\item \tbf{MPLS modules}. Additional modules are needed for MPLS
simulations. The \nedtype{MPLS} module is placed between the network layer
and NICs, and implements label switching. \nedtype{MPLS} requires a
\nedtype{LIB} module (Label Information Base) to be present in the router
which it accesses via C++ function calls. MPLS control protocol
implementations (e.g. the \nedtype{RSVP} module) manage the information in
\nedtype{LIB} via C++ calls.

\item \tbf{Relay unit}. Ethernet (and possibly other) switch models may
contain a relay unit, which switches frames among Ethernet (and other
IEEE 802) NICs. Concrete relay unit types include \nedtype{MACRelayUnit}
and \nedtype{Ieee8021dRelay}, which differ in their performance models.

\ifdraft TODO
\item \tbf{Power consumption}. INET extensions uses for wireless sensor
networks (WSNs) may add a battery module to the node model. The battery
module would keep track of energy consumption. A battery module is provided
e.g. by the INETMANET project.
\fi

\end{itemize}

The \nedtype{StandardHost} and \nedtype{Router} predefined NED types are
only one possible example of host/router models, and they do not contain
all the above components; for specific simulations it is a perfectly
valid approach to create custom node models.

Most modules are optional, i.e. can be left out of hosts or other node
models when not needed in the given scenario. For example, switch models do
not need a network layer, a routing table or interface table. Some NICs (e.g.
\nedtype{EtherMAC}) can be used without and interface table and queue models as
well.

\ifdraft TODO
The notification board (\nedtype{NotificationBoard}) and the interface
table (\nedtype{InterfaceTable}) will be described later in this chapter.
Other modules are covered in later chapters, i.e. \nedtype{IPv4RoutingTable}
in the IPv4 chapter.
\fi

\section{Addresses}

The INET Framework uses a number of C++ classes to represent various
addresses in the network. These classes support initialization and
assignment from binary and string representation of the address, and
accessing the address in both forms. (Storage is in binary form). They also
support the "unspecified" special value (and the \ffunc{isUnspecified()}
method) that corresponds to the all-zeros address.

\begin{itemize}
  \item \cppclass{MACAddress} represents a 48-bit IEEE 802 MAC address. The
    textual notation it understands and produces is hex string.

  \item \cppclass{IPv4Address} represents a 32-bit IPv4 address. It can parse
    and produce textual representations in the "dotted decimal" syntax.

  \item \cppclass{IPv6Address} represents a 128-bit IPv6 address. It can parse
    and produce address strings in the canonical (RFC 3513) syntax.

  \item \cppclass{L3Address} is conceptually a union of a \cppclass{IPv4Address}
    and \cppclass{IPv6Address}: an instance stores either an IPv4 address or an
    IPv6 address. \cppclass{L3Address} is mainly used in the transport layer and above
    to abstract away network addresses. It can be assigned from both \cppclass{IPv4Address}
    and \cppclass{IPv6Address}, and can also parse string representations of both.
    The \ffunc{getType()}, \ffunc{toIPv4()} and \ffunc{toIPv6()} methods can be used
    to access the value.
\end{itemize}

\ifdraft TODO
TODO: Resolving addresses with L3AddressResolver
\fi


\ifdraft TODO
\section{The Notification Board}

The \nedtype{NotificationBoard} module allows publish-subscribe
communication among modules within a host. Using
\nedtype{NotificationBoard}, modules can notify each other about
events such as routing table changes, interface status changes
(up/down), interface configuration changes, wireless handovers, changes in
the state of the wireless channel, mobile node position changes, etc.
\nedtype{NotificationBoard} acts as a intermediary between the module where
the events occur and modules which are interested in learning about
those events.

\nedtype{NotificationBoard} has exactly one instance within a host or
router model, and it is accessed via direct C++ method calls (not message
exchange). Modules can \textit{subscribe} to categories of changes
(e.g. ``routing table changed'' or ``radio channel became empty''). When
such a change occurs, the corresponding module (e.g. the
\nedtype{IPv4RoutingTable} or the physical layer module) will let
\nedtype{NotificationBoard} know, and it will disseminate this information
to all interested modules.

\sloppypar Notification events are grouped into \textit{categories}.
Examples of categories are: \ttt{NF\_HOSTPOSITION\_UPDATED},
\ttt{NF\_RADIOSTATE\_CHANGED}, \ttt{NF\_PP\_TX\_BEGIN},
\ttt{NF\_PP\_TX\_END}, \ttt{NF\_IPv4\_ROUTE\_ADDED},
\ttt{NF\_BEACON\_LOST}, \ttt{NF\_NODE\_FAILURE}, \ttt{NF\_NODE\_RECOVERY},
etc. Each category is identified by an integer (right now it's assigned in
the source code via an enum, in the future we'll convert to dynamic
category registration).

To trigger a notification, the client must obtain a pointer to the
\nedtype{NotificationBoard} of the given host or router (explained later),
and call its \ffunc{fireChangeNotification()} method. The notification will
be delivered to all subscribed clients immediately, inside the
\ffunc{fireChangeNotification()} call.

Clients that wish to receive notifications should implement (subclass from)
the \cppclass{INotifiable} interface, obtain a pointer to the
\nedtype{NotificationBoard}, and subscribe to the categories they are
interested in by calling the \ffunc{subscribe()} method of the
\nedtype{NotificationBoard}. Notifications will be delivered to the
\ffunc{receiveChangeNotification()} method of the client (redefined from
\cppclass{INotifiable}).

In cases when the category itself (an \ttt{int}) does not carry enough
information about the notification event, one can pass additional
information in a data class. There is no restriction on what the data class
may contain, except that it has to be subclassed from \cppclass{cObject},
and of course producers and consumers of notifications should agree on its
contents. If no extra info is needed, one can pass a \ttt{NULL} pointer in
the \ffunc{fireChangeNotification()} method.

A module which implements \cppclass{INotifiable} looks like this:

\begin{cpp}
class Foo : public cSimpleModule, public INotifiable {
    ...
    virtual void receiveChangeNotification(int category, const cObject *details) {..}
    ...
};
\end{cpp}

Note: \cppclass{cObject} was called \cppclass{cPolymorphic} in earlier versions
of OMNeT++. You may occasionally still see the latter name in source code; it
is an alias (typedef) to \cppclass{cObject}.

Obtaining a pointer to the \nedtype{NotificationBoard} module of that host/router:

\begin{cpp}
NotificationBoard *nb; // this is best made a module class member
nb = NotificationBoardAccess().get();  // best done in initialize()
\end{cpp}

TODO how to fire a notification
\fi


\section{The Interface Table}

The \nedtype{InterfaceTable} module holds one of the key data structures in
the INET Framework: information about the network interfaces in the host.
The interface table module does not send or receive messages; other modules
access it using standard C++ member function calls.

\ifdraft TODO
\subsection{Accessing the Interface Table}

If a module wants to work with the interface table, first it needs to obtain a
pointer to it. This can be done with the help of the
\cppclass{InterfaceTableAccess} utility class:

\begin{cpp}
IInterfaceTable *ift = InterfaceTableAccess().get();
\end{cpp}

\cppclass{InterfaceTableAccess} requires the interface table module to be a
direct child of the host and be called \ttt{"interfaceTable"} in order to
be able to find it. The \ffunc{get()} method never returns \ttt{NULL}: if
it cannot find the interface table module or cannot cast it to the
appropriate C++ type (\cppclass{IInterfaceTable}), it throws an exception
and stop the simulation with an error message.

For completeness, \cppclass{InterfaceTableAccess} also has a
\ffunc{getIfExists()} method which can be used if the code does not require
the presence of the interface table. This method returns \ttt{NULL} if the
interface table cannot be found.

Note that the returned C++ type is \cppclass{IInterfaceTable}; the initial
"\ttt{I}" stands for "interface". \cppclass{IInterfaceTable} is an abstract
class interface that \cppclass{InterfaceTable} implements. Using the abstract
class interface allows one to transparently replace the interface table with
another implementation, without the need for any change or even
recompilation of the INET Framework.
\fi

\subsection{Interface Entries}

Interfaces in the interface table are represented with the
\cppclass{InterfaceEntry} class. \cppclass{IInterfaceTable} provides member
functions for adding, removing, enumerating and looking up interfaces.

Interfaces have unique names and interface IDs; either can be used to look up
an interface (IDs are naturally more efficient). Interface IDs are invariant to
the addition and removal of other interfaces.

Data stored by an interface entry include:

\begin{itemize}
  \item \textit{name} and \textit{interface ID} (as described above)
  \item \textit{MTU}: Maximum Transmission Unit, e.g. 1500 on Ethernet
  \item several flags:
    \begin{itemize}
      \item \textit{down}: current state (up or down)
      \item \textit{broadcast}: whether the interface supports broadcast
      \item \textit{multicast} whether the interface supports multicast
      \item \textit{pointToPoint}: whether the interface is point-to-point link
      \item \textit{loopback}: whether the interface is a loopback interface
    \end{itemize}
  \item \textit{datarate} in bit/s
  \item \textit{link-layer address} (for now, only IEEE 802 MAC addresses are supported)
  \item \textit{network-layer gate index}: which gate of the network layer within the host the NIC is connected to
  \item \textit{host gate IDs}: the IDs of the input and output gate of the host the NIC is connected to
\end{itemize}

\tbf{Extensibility}. You have probably noticed that the above list does not
contain data such as the IPv4 or IPv6 address of the interface. Such
information is not part of \cppclass{InterfaceEntry} because we do not want
\nedtype{InterfaceTable} to depend on either the IPv4 or the IPv6 protocol
implementation; we want both to be optional, and we want
\nedtype{InterfaceTable} to be able to support possibly other network
protocols as well.

Thus, extra data items are added to \cppclass{InterfaceEntry} via
extension. Two kinds of extensions are envisioned: extension by the link
layer (i.e. the NIC), and extension by the network layer protocol:

\begin{itemize}

\item \tbf{NICs} can extend interface entries via C++ class inheritance, that is, by
simply subclassing \cppclass{InterfaceEntry} and adding extra data and
functions. This is possible because NICs create and register entries in
\nedtype{InterfaceTable}, so in their code one can just write
\ttt{new MyExtendedInterfaceEntry()} instead of \ttt{new InterfaceEntry()}.

\item \textbf{Network layer protocols} cannot add data via subclassing, so
composition has to be used. \cppclass{InterfaceEntry} contains pointers to
network-layer specific data structures. For example, there are pointers to
IPv4 specific data, and IPv6 specific data. These objects can be accessed with
the following \cppclass{InterfaceEntry} member functions: \ffunc{ipv4Data()},
\ffunc{ipv6Data()}, and \ffunc{getGenericNetworkProtocolData()}.
They return pointers of the types \cppclass{IPv4InterfaceData},
\cppclass{IPv6InterfaceData}, and \cppclass{GenericNetworkProtocolInterfaceData},
respectively. For illustration, \cppclass{IPv4InterfaceData} is installed
onto the interface entries by the \nedtype{IPv4RoutingTable} module, and it
contains data such as the IP address of the interface, the netmask, link
metric for routing, and IP multicast addresses associated with the
interface. A protocol data pointer will be \ttt{NULL} if the corresponding
network protocol is not used in the simulation; for example, in IPv4
simulations only \ffunc{ipv4Data()} will return a non-\ttt{NULL} value.


\end{itemize}


\subsection{Interface Registration}

Interfaces are registered dynamically in the initialization phase by modules
that represent network interface cards (NICs). The INET Framework makes use
of the multi-stage initialization feature of OMNeT++, and interface registration takes
place in the first stage (i.e. stage \ttt{INITSTAGE\_LINK\_LAYER}).

Example code that performs interface registration:

\begin{cpp}
void PPP::initialize(int stage)
{
    if (stage == INITSTAGE_LINK_LAYER) {
        ...
        interfaceEntry = registerInterface(datarate);
    ...
}

InterfaceEntry *PPP::registerInterface(double datarate)
{
    InterfaceEntry *e = new InterfaceEntry(this);

    // interface name: NIC module's name without special characters ([])
    e->setName(OPP_Global::stripnonalnum(getParentModule()->getFullName()).c_str());

    // data rate
    e->setDatarate(datarate);

    // generate a link-layer address to be used as interface token for IPv6
    InterfaceToken token(0, simulation.getUniqueNumber(), 64);
    e->setInterfaceToken(token);

    // set MTU from module parameter of similar name
    e->setMtu(par("mtu"));

    // capabilities
    e->setMulticast(true);
    e->setPointToPoint(true);

    // add
    IInterfaceTable *ift = findModuleFromPar<IInterfaceTable>(par("interfaceTableModule"), this);
    ift->addInterface(e);

    return e;
}
\end{cpp}


\ifdraft TODO
\subsection{Interface Change Notifications}

\nedtype{InterfaceTable} has a change notification mechanism built in, with
the granularity of interface entries.

Clients that wish to be notified when something changes in
\nedtype{InterfaceTable} can subscribe to the following notification
categories in the host's \nedtype{NotificationBoard}:

\begin{itemize}
  \item \tbf{\ttt{NF\_INTERFACE\_CREATED}}: an interface entry has been
    created and added to the interface table
  \item \tbf{\ttt{NF\_INTERFACE\_DELETED}}: an interface entry is going
    to be removed from the interface table. This is a pre-delete
    notification so that clients have access to interface data that are
    possibly needed to react to the change
% TODO hmmm -- rename the constant? also fire a post-change notification??
  \item \tbf{\ttt{NF\_INTERFACE\_CONFIG\_CHANGED}}: a configuration setting
    in an interface entry has changed (e.g. MTU or IP address)
  \item \tbf{\ttt{NF\_INTERFACE\_STATE\_CHANGED}}: a state variable in an
    interface entry has changed (e.g. the up/down flag)
\end{itemize}

In all those notifications, the data field is a pointer to the
corresponding \cppclass{InterfaceEntry} object. This is even true for
\ttt{NF\_INTERFACE\_DELETED} (which is actually a pre-delete notification).
\fi

\ifdraft TODO
\section{Initialization Stages}

Node architecture makes it necessary to use multi-stage initialization.
What happens in each stage is this:

In stage 0, interfaces register themselves in \nedtype{InterfaceTable} modules

In stage 1, routing files are read.

In stage 2, network configurators (e.g. \nedtype{FlatNetworkConfiguration})
assign addresses and set up routing tables.

In stage 3, TODO...

In stage 4, TODO...

...

The multi-stage initialization process itself is described in the OMNeT++ Manual.
\fi

\section{Communication between protocol layers}

In the INET Framework, when an upper-layer protocol wants to send a data
packet over a lower-layer protocol, the upper-layer module just sends the
message object representing the packet to the lower-layer module, which
will in turn encapsulate it and send it. The reverse process takes place
when a lower layer protocol receives a packet and sends it up after
decapsulation.

It is often necessary to convey extra information with the packet. For
example, when an application-layer module wants to send data over TCP, some
connection identifier needs to be specified for TCP. When TCP sends a
segment over IP, IP will need a destination address and possibly other
parameters like TTL. When IP sends a datagram to an Ethernet interface for
transmission, a destination MAC address must be specified. This extra
information is attached to the message object to as \textit{control info}.

Control info are small value objects, which are attached to packets
(message objects) with its \ttt{setControlInfo()} member function.
Control info only holds auxiliary information for the next protocol layer,
and is not supposed to be sent over the network to other hosts and routers.


\ifdraft TODO
\section{Publish-Subscribe Communication within Nodes}

The \nedtype{NotificationBoard} module makes it possible for several modules to
communicate in a publish-subscribe manner. For example, the radio module
(\nedtype{Ieee80211Radio}) fires a \textit{"radio state changed"} notification when
the state of the radio channel changes (from TRANSMIT to IDLE, for example),
and it will be delivered to other modules that have previously subscribed
to that notification category. The notification mechanism uses C++ functions
calls, no message sending is involved.

The notification board submodule within the host (router) must be called
\ttt{notificationBoard} for other modules to find it.
\fi

\ifdraft TODO
\section{Network interfaces}

todo...
\fi

\ifdraft TODO
\section{The wireless infrastructure}

todo...
\fi


\section{NED Conventions}

\subsection{The @node Property}

By convention, compound modules that implement network devices (hosts,
routers, switches, access points, base stations, etc.) are marked with the
\ttt{@node} NED property. As node models may themselves be hierarchical, the
\ttt{@node} property is used by protocol implementations and other simple
modules to determine which ancestor compound module represents the physical
network node they live in.

\subsection{The @labels Module Property}

The \ttt{@labels} property can be added to modules and gates, and it
allows the OMNeT++ graphical editor to provide better editing experience.
First we look at \ttt{@labels} as a module property.

\ttt{@labels(node)} has been added to all NED module types that may occur on
network level. When editing a network, the graphical editor will NED types
with \ttt{@labels(node)} to the top of the component palette, allowing the
user to find them easier.

Other labels can also be specified in the \ttt{@labels(...)} property. This
has the effect that if one module with a particular label has already been
added to the compound module being edited, other module types with the same
label are also brought to the top of the palette. For example,
\nedtype{EtherSwitch} is annotated with \ttt{@labels(node,ethernet-node)}.
When you drop an \nedtype{EtherSwitch} into a compound module, that will
bring \nedtype{EtherHost} (which is also tagged with the
\ttt{ethernet-node} label) to the top of the palette, making it easier to
find.

\begin{ned}
module EtherSwitch
{
    parameters:
        @node();
        @labels(node,ethernet-node);
        @display("i=device/switch");
    ...
}
\end{ned}

Module types that are already present in the compound module also appear in
the top part of the palette. The reason is that if you already added a
\nedtype{StandardHost}, for example, then you are likely to add more of the
same kind. Gate labels (see next section) also affect palette order: modules
which can be connected to modules already added to the compound module
will also be listed at the top of the palette. The final ordering is the
result of a scoring algorithm.


\subsection{The @labels Gate Property}

Gates can also be labelled with \ttt{@labels()}; the purpose is to make it easier
to connect modules in the editor. If you connect two modules in the editor,
the gate selection menu will list gate pairs that have a label in common.

\ifdraft TODO
screenshot
\fi

For example, when connecting hosts and routers, the editor will offer connecting
Ethernet gates with Ethernet gates, and PPP gates with PPP gates. This is the
result of gate labelling like this:

\begin{ned}
module StandardHost
{
    ...
    gates:
        inout pppg[] @labels(PPPFrame-conn);
        inout ethg[] @labels(EtherFrame-conn);
    ...
}
\end{ned}

Guidelines for choosing gate label names: For gates of modules that
implement protocols, use the C++ class name of the packet or acompanying
control info (see later) associated with the gate, whichever applies;
append \ttt{/up} or \ttt{/down} to the name of the control info class. For
gates of network nodes, use the class names of packets (frames) that travel
on the corresponding link, with the \ttt{-conn} suffix. The suffix prevents
protocol-level modules to be promoted in the graphical editor palette when
a network is edited.

Examples:

\begin{ned}
simple TCP like ITCP
{
    ...
    gates:
        input appIn[] @labels(TCPCommand/down);
        output appOut[] @labels(TCPCommand/up);
        input ipIn @labels(TCPSegment,IPv4ControlInfo/up,IPControlInfo/up);
        output ipOut @labels(TCPSegment,IPv4ControlInfo/down,IPv6ControlInfo/up);
}
\end{ned}


\begin{ned}
simple PPP
{
    ...
    gates:
        input netwIn;
        output netwOut;
        inout phys @labels(PPPFrame);
}
\end{ned}



%%% Local Variables:
%%% mode: latex
%%% TeX-master: "usman"
%%% End:

